package com.example.dailyrecord.service.impl;

import com.example.dailyrecord.entity.EmailContent;
import com.example.dailyrecord.entity.Record;
import com.example.dailyrecord.entity.StatusCode;
import com.example.dailyrecord.entity.User;
import com.example.dailyrecord.service.EmailService;
import com.example.dailyrecord.service.RecordService;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
public class EmailServiceImpl implements EmailService {
    @Resource
    private JavaMailSenderImpl mailSender;
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private RecordService recordService;
    private static final String SEND_TIMES = "_SEND_TIMES";

    private void send(SimpleMailMessage mailMessage) {
        mailSender.send(mailMessage);
    }

    @Override
    public @NotNull String getFrom() {
        return mailSender.getUsername();
    }

    @Override
    public void sendNoteEmail() {
        List<String> list = recordService.notFinishedToday().stream()
                .map(Record::getUid).collect(Collectors.toList());
        for (String s : list) {
            sendEmail(EmailContent.NOTICE_EMAIL, s, "");
        }
    }

    @Override
    public StatusCode sendCode(HttpServletRequest request, HttpServletResponse response) {
        String address = request.getParameter(User.EMAIL_NAME);
        int type = Integer.parseInt(request.getParameter("type"));
        if (checkSend(address)) {
            EmailContent emailContent = EmailContent.getContent(type);
            String code = RandomStringUtils.randomNumeric(8);
            sendEmail(emailContent, address, code);
            stringRedisTemplate.opsForValue().set(address + emailContent.getAction(), code, 5, TimeUnit.MINUTES);
            stringRedisTemplate.opsForValue().set(address + SEND_TIMES, "1", 5, TimeUnit.MINUTES);
            return StatusCode.MAIL_SEND_SUCCESS;
        } else {
            return StatusCode.MAIL_SEND_LOT;
        }
    }

    private void sendEmail(EmailContent emailContent, String address, String content) {
        SimpleMailMessage mailMessage = new SimpleMailMessage();
        mailMessage.setFrom(getFrom());
        mailMessage.setTo(address);
        mailMessage.setSubject(emailContent.getSubject());
        mailMessage.setText(String.format(emailContent.getContent(), content));
        send(mailMessage);
    }

    private boolean checkSend(String emailAddress) {
        String count = stringRedisTemplate.opsForValue().get(emailAddress + SEND_TIMES);
        return StringUtils.isEmpty(count);
    }
}
